package com.leisurexi.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Iterator;

/**
 * Nio 非阻塞式服务端
 *
 * @author: leisurexi
 * @date: 2021-01-05 23:17
 */
public class NoBlockServer {

    public static void main(String[] args) {
        try {
            //  获取 socket 通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 设置为非阻塞
            serverSocketChannel.configureBlocking(false);
            //  绑定端口
            serverSocketChannel.bind(new InetSocketAddress(8888));
            // 创建 selector
            Selector selector = Selector.open();
            // 将通道注册到 selector 并关注 连接 事件
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            // 轮询获取 selector 上就绪的事件
            while (selector.select() > 0) {
                // 获取已就绪的事件
                Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey selectionKey = keyIterator.next();
                    if (selectionKey.isAcceptable()) {
                        // 获取客户端的连接
                        SocketChannel client = serverSocketChannel.accept();
                        // 设置为非阻塞
                        client.configureBlocking(false);
                        // 绑定到 selector 上，并关注读事件
                        client.register(selector, SelectionKey.OP_READ);
                    }
                    if (selectionKey.isReadable()) {
                        // 获取就绪的通道
                        SocketChannel client = (SocketChannel) selectionKey.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        //  得到文件通道，不存在自动创建
                        FileChannel fileChannel = FileChannel.open(Paths.get("C:\\Users\\lwx\\Desktop\\goddess.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
                        while (client.read(buffer) > 0) {
                            buffer.flip();
                            fileChannel.write(buffer);
                            buffer.clear();
                        }
                        // 回复客户端接收成功
                        buffer.put("SUCCESS".getBytes());
                        buffer.flip();
                        client.write(buffer);
                        buffer.clear();
                    }
                    keyIterator.remove();
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
